package com.dl698.axdr;

import com.dl698.asn1.axdr.AxdrType;
import com.dl698.util.ReverseByteArrayInputStream;
import com.dl698.util.ReverseByteArrayOutputStream;

/**
 * AxdrDateTime类
 * 实现日期时间数据的编解码
 * 
 * @author wind
 * @version 1.1.1
 */
public class AxdrDateTime implements AxdrType {
    private short year = 0;
    private short month = 0;
    private short dayOfMonth = 0;
    private short dayOfWeek = 0;
    private short hour = 0;
    private short minute = 0;
    private short second = 0;
    private short hundredths = 0;
    private short deviation = 0;
    private short clockStatus = 0;
    private byte[] dataCode = null;

    public AxdrDateTime() {
    }

    public short getYear() {
        return year;
    }

    public void setYear(short year) {
        this.year = year;
    }

    public short getMonth() {
        return month;
    }

    public void setMonth(short month) {
        this.month = month;
    }

    public short getDayOfMonth() {
        return dayOfMonth;
    }

    public void setDayOfMonth(short dayOfMonth) {
        this.dayOfMonth = dayOfMonth;
    }

    public short getDayOfWeek() {
        return dayOfWeek;
    }

    public void setDayOfWeek(short dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    public short getHour() {
        return hour;
    }

    public void setHour(short hour) {
        this.hour = hour;
    }

    public short getMinute() {
        return minute;
    }

    public void setMinute(short minute) {
        this.minute = minute;
    }

    public short getSecond() {
        return second;
    }

    public void setSecond(short second) {
        this.second = second;
    }

    public short getHundredths() {
        return hundredths;
    }

    public void setHundredths(short hundredths) {
        this.hundredths = hundredths;
    }

    public short getDeviation() {
        return deviation;
    }

    public void setDeviation(short deviation) {
        this.deviation = deviation;
    }

    public short getClockStatus() {
        return clockStatus;
    }

    public void setClockStatus(short clockStatus) {
        this.clockStatus = clockStatus;
    }

    public byte[] getDataCode() {
        return dataCode;
    }

    public void setDataCode(byte[] dataCode) {
        this.dataCode = dataCode;
    }

    @Override
    public int decode(ReverseByteArrayInputStream input) {
        int codeLength = 0;

        // 解码年份
        AxdrUnsigned16 yearField = new AxdrUnsigned16();
        codeLength += yearField.decode(input);
        this.year = (short) yearField.getValue();

        // 解码月份
        AxdrUnsigned8 monthField = new AxdrUnsigned8();
        codeLength += monthField.decode(input);
        this.month = monthField.getValue();

        // 解码日期
        AxdrUnsigned8 dayOfMonthField = new AxdrUnsigned8();
        codeLength += dayOfMonthField.decode(input);
        this.dayOfMonth = dayOfMonthField.getValue();

        // 解码星期
        AxdrUnsigned8 dayOfWeekField = new AxdrUnsigned8();
        codeLength += dayOfWeekField.decode(input);
        this.dayOfWeek = dayOfWeekField.getValue();

        // 解码小时
        AxdrUnsigned8 hourField = new AxdrUnsigned8();
        codeLength += hourField.decode(input);
        this.hour = hourField.getValue();

        // 解码分钟
        AxdrUnsigned8 minuteField = new AxdrUnsigned8();
        codeLength += minuteField.decode(input);
        this.minute = minuteField.getValue();

        // 解码秒
        AxdrUnsigned8 secondField = new AxdrUnsigned8();
        codeLength += secondField.decode(input);
        this.second = secondField.getValue();

        // 解码百分之一秒
        AxdrUnsigned8 hundredthsField = new AxdrUnsigned8();
        codeLength += hundredthsField.decode(input);
        this.hundredths = hundredthsField.getValue();

        // 解码偏差
        AxdrInteger16 deviationField = new AxdrInteger16();
        codeLength += deviationField.decode(input);
        this.deviation = deviationField.getValue();

        // 解码时钟状态
        AxdrUnsigned8 clockStatusField = new AxdrUnsigned8();
        codeLength += clockStatusField.decode(input);
        this.clockStatus = clockStatusField.getValue();

        return codeLength;
    }

    @Override
    public int encode(ReverseByteArrayOutputStream output) {
        int codeLength = 0;

        // 编码年份
        AxdrUnsigned16 yearField = new AxdrUnsigned16();
        yearField.setValue(this.year);
        codeLength += yearField.encode(output);

        // 编码月份
        AxdrUnsigned8 monthField = new AxdrUnsigned8();
        monthField.setValue(this.month);
        codeLength += monthField.encode(output);

        // 编码日期
        AxdrUnsigned8 dayOfMonthField = new AxdrUnsigned8();
        dayOfMonthField.setValue(this.dayOfMonth);
        codeLength += dayOfMonthField.encode(output);

        // 编码星期
        AxdrUnsigned8 dayOfWeekField = new AxdrUnsigned8();
        dayOfWeekField.setValue(this.dayOfWeek);
        codeLength += dayOfWeekField.encode(output);

        // 编码小时
        AxdrUnsigned8 hourField = new AxdrUnsigned8();
        hourField.setValue(this.hour);
        codeLength += hourField.encode(output);

        // 编码分钟
        AxdrUnsigned8 minuteField = new AxdrUnsigned8();
        minuteField.setValue(this.minute);
        codeLength += minuteField.encode(output);

        // 编码秒
        AxdrUnsigned8 secondField = new AxdrUnsigned8();
        secondField.setValue(this.second);
        codeLength += secondField.encode(output);

        // 编码百分之一秒
        AxdrUnsigned8 hundredthsField = new AxdrUnsigned8();
        hundredthsField.setValue(this.hundredths);
        codeLength += hundredthsField.encode(output);

        // 编码偏差
        AxdrInteger16 deviationField = new AxdrInteger16();
        deviationField.setValue(this.deviation);
        codeLength += deviationField.encode(output);

        // 编码时钟状态
        AxdrUnsigned8 clockStatusField = new AxdrUnsigned8();
        clockStatusField.setValue(this.clockStatus);
        codeLength += clockStatusField.encode(output);

        return codeLength;
    }

    /**
     * 编码并保存
     * 
     * @param encodingSizeGuess 编码大小预估
     */
    public void encodeAndSave(int encodingSizeGuess) {
        ReverseByteArrayOutputStream revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        this.encode(revOStream);
        this.dataCode = revOStream.getArray();
    }

    @Override
    public String toString() {
        return String.format("%04d-%02d-%02d %02d:%02d:%02d.%02d",
                this.year, this.month, this.dayOfMonth,
                this.hour, this.minute, this.second, this.hundredths);
    }
}